﻿//===============================================================================
// PostSharp Poco implementation for EntityFramework
//===============================================================================
// Copyright © Ruurd Boeke.  All rights reserved.
// THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY
// OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT
// LIMITED TO THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
// FITNESS FOR A PARTICULAR PURPOSE.
//===============================================================================
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using PostSharp.Laos;
using System.ComponentModel;
using EntityFrameworkContrib.PostSharp4EF;

namespace EditableBusinessObjects.Postsharp.Public
{
    /// <summary>
    /// Implementation of <see cref="OnMethodBoundaryAspect"/> that raises the 
    /// <see cref="INotifyPropertyChanged.PropertyChanged"/> event when a property set
    /// accessor completes successfully.
    /// </summary>
    [Serializable]
    class OnPropertySetNotifyPropertyChangedSubAspect : OnMethodBoundaryAspect
    {
        private readonly string propertyName;

        /// <summary>
        /// Initializes a new <see cref="OnPropertySetNotifyPropertyChangedSubAspect"/>.
        /// </summary>
        /// <param name="propertyName">Name of the property to which this set accessor belong.</param>
        /// <param name="parent">Parent <see cref="NotifyPropertyChangedAttribute"/>.</param>
        public OnPropertySetNotifyPropertyChangedSubAspect(string propertyName, int aspectPriority)
        {
            this.AspectPriority = aspectPriority;
            this.propertyName = propertyName;
        }

        /// <summary>
        /// Executed when the set accessor successfully completes. Raises the 
        /// <see cref="INotifyPropertyChanged.PropertyChanged"/> event.
        /// </summary>
        /// <param name="eventArgs">Event arguments with information about the 
        /// current execution context.</param>
        public override void OnSuccess(MethodExecutionEventArgs eventArgs)
        {
            // Get the implementation of INotifyPropertyChanged. We have access to it through the IComposed interface,
            // which is implemented at compile time.
            NotifyPropertyChangedImplementation implementation =
                (NotifyPropertyChangedImplementation)
                ((IComposed<INotifyPropertyChanged>)eventArgs.Instance).GetImplementation(
                    eventArgs.InstanceCredentials);

            // Raises the PropertyChanged event.
            implementation.OnPropertyChanged(this.propertyName);
        }
    }
}
